package com.github.anastr.speedviewlib;

import com.github.anastr.speedviewlib.util.AttrSetUtils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.app.Context;

public class ProgressiveGauge extends LinearGauge {

    /**
     * the shape
     */
    private Path path = new Path();

    private Paint frontPaint = new Paint(), backPaint = new Paint();

    public ProgressiveGauge(Context context) {
        this(context, null);
    }

    public ProgressiveGauge(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public ProgressiveGauge(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        frontPaint.setAntiAlias(true);
        backPaint.setAntiAlias(true);
        init();
        initAttributeSet(context, attrSet);
    }

    @Override
    protected void defaultGaugeValues() {
        super.setSpeedTextPosition(Position.CENTER);
        super.setUnitUnderSpeedText(true);
    }

    private void init() {
        frontPaint.setColor(new Color(0xFF00FFFF));
        backPaint.setColor(new Color(0xffd6d7d7));
    }

    private void initAttributeSet(Context context, AttrSet attrs) {
        if (attrs == null)
            return;

        frontPaint.setColor(AttrSetUtils.getAttrSetColor(attrs, "sv_speedometerColor", frontPaint.getColor()));
        backPaint.setColor(AttrSetUtils.getAttrSetColor(attrs, "sv_speedometerBackColor", backPaint.getColor()));
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        int w = EstimateSpec.getSize(widthMeasureSpec);
        int h = EstimateSpec.getSize(heightMeasureSpec);

        if (getOrientation() == Orientation.HORIZONTAL) {
            if (h > w / 2)
                setEstSize(w, w / 2);
            else
                setEstSize(h * 2, h);
        } else {
            if (w > h / 2)
                setEstSize(h / 2, h);
            else
                setEstSize(w, w * 2);
        }
        super.onEstimateSize(widthMeasureSpec,heightMeasureSpec);
        return true;
    }

    private void setEstSize(int width, int height) {
        setEstimatedSize(
                Component.EstimateSpec.getChildSizeWithMode(width, width, Component.EstimateSpec.PRECISE),
                Component.EstimateSpec.getChildSizeWithMode(height, height, Component.EstimateSpec.PRECISE)
        );
    }

    @Override
    protected void updateFrontAndBackBitmaps() {
        updateOrientation();
        Canvas canvasBack = createBackgroundBitmapCanvas();
        Canvas canvasFront = createForegroundBitmapCanvas();

        canvasBack.translate(getCustomPadding(), getCustomPadding());
        canvasBack.drawPath(path, backPaint);

        canvasFront.drawPath(path, frontPaint);
    }

    private void updateOrientation() {
        if (getOrientation() == Orientation.HORIZONTAL)
            updateHorizontalPath();
        else
            updateVerticalPath();
    }

    /**
     * to reset {@link #path} for horizontal shape.
     */
    protected void updateHorizontalPath() {
        path.reset();
        path.moveTo(0f, getHeightPa());
        path.lineTo(0f, getHeightPa() - getHeightPa() * .1f);
        path.quadTo(getWidthPa() * .75f, getHeightPa() * .75f
                , getWidthPa(), 0f);
        path.lineTo(getWidthPa(), getHeightPa());
        path.lineTo(0f, getHeightPa());
    }

    /**
     * to reset {@link #path} for vertical shape.
     */
    protected void updateVerticalPath() {
        path.reset();
        path.moveTo(0f, getHeightPa());
        path.lineTo(getWidthPa() * .1f, getHeightPa());
        path.quadTo(getWidthPa() * .25f, getHeightPa() * .25f
                , getWidthPa(), 0f);
        path.lineTo(0f, 0f);
        path.lineTo(0f, getHeightPa());
    }

    /**
     * @return foreground progress color.
     */
    public int getSpeedometerColor() {
        return frontPaint.getColor().getValue();
    }

    /**
     * change the color of progress.
     *
     * @param speedometerColor new color.
     */
    public void setSpeedometerColor(int speedometerColor) {
        frontPaint.setColor(new Color(speedometerColor));
        if (!isAttachedToWindow())
            return;
        updateBackgroundBitmap();
        invalidate();
    }

    /**
     * @return background progress color.
     */
    public int getSpeedometerBackColor() {
        return backPaint.getColor().getValue();
    }

    /**
     * change the color of background progress.
     *
     * @param speedometerBackColor new color.
     */
    public void setSpeedometerBackColor(int speedometerBackColor) {
        backPaint.setColor(new Color(speedometerBackColor));
        if (!isAttachedToWindow())
            return;
        updateBackgroundBitmap();
        invalidate();
    }
}
